import urllib2
import os, os.path
import sys
import re

class Serial(object):
    def __init__(self, nume = '', sezon = 0, episod = 0):
        self.__nume   = nume
        self.__sezon  = sezon
        self.__episod = episod
    
    @property
    def nume(self):
        return self.__nume
        
    @nume.setter
    def nume(self, nume):
        self.__nume = nume.replace(' ', '_')
        
    @property
    def sezon(self):
        return str(self.__sezon)
    
    @sezon.setter
    def sezon(self, sezon):
        try:
            self.__sezon = int(sezon)
        except ValueError:
            print('bad season')
            exit(1)
        
    @property
    def episod(self):
        return str(self.__episod)
        
    @episod.setter
    def episod(self, episod):
        try:
            self.__episod = int(episod)
        except ValueError:
            print('bad episode')
            exit(1)
        
    def creeazaURL(self):
        return ('http://www.addic7ed.com/serie/' + self.nume + '/' + self.sezon 
                + '/' + self.episod + '/addic7ed/')
        
    def __str__(self):
        return (self.nume + ', sezonul ' + self.sezon + 
                ', episodul ' + self.episod)

class Addict(object):
    
    def __init__(self):
        self.__tabel_sub = []
        self.__fis_cfg = os.path.expanduser('~' + os.sep + '.addict')
        self.serial = Serial()
        self.__alias = {}
        self.__dl_dir = self.defaultDir()
    
    def defaultDir(self):
        #directorul default ar fi desktop-ul
        return os.path.expanduser('~' + os.sep + 'Desktop' + os.sep)
        
    def config(self):
        try:
            with open(self.__fis_cfg) as f:
                alias = False
                dl_dir = False
                for l in f:
                    l = l.strip() # fara \n de la final
                    if l == '[alias]':
                        alias = True
                        continue
                    if l == '[dl_dir]':
                        dl_dir = True
                        continue
                    if dl_dir == True:
                        self.__dl_dir = l
                        dl_dir = False
                        continue
                    if alias == True:
                        lin_sep = l.split('=')
                        self.__alias[lin_sep[0]] = lin_sep[1]
                        
        except IOError:
            pass
                        
    def deschideURL(self, url):
        req = urllib2.Request(url, headers = {'Referer': url, 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2)'})
        try:
            rasp = urllib2.urlopen(req)
            return rasp
			
        except urllib2.HTTPError, e:
            print('error: ', e.code)
            exit(1)
        except urllib2.URLError:
            print('server not found')
            exit(1)
            
    def cautaSubtitrari(self):
        pag = self.deschideURL(self.serial.creeazaURL()).read()
        # 1. caut toate versiunile; in indicii pari va fi informatia split-uita
        #    iar in indicii impari versiunea gasita
        ver_split = re.split('(Version .+, [0-9]*.[0-9]* MBs)', pag)
        n_ver = len(ver_split)
        # ce-i in indicele 0 nu ma intereseaza
        i_ver = 2 
        while i_ver < n_ver:
            # 2. caut toate limbile pt versiunea curenta
            limbi = ver_split[i_ver].split('"language"')
            i_lb = 1
            n_lb = len(limbi)
            while i_lb < n_lb:
                # 3. verific daca subtitrarea e 100% terminata
                if re.search('[0-9]+.[0-9]+% Completed', limbi[i_lb]):
                    i_lb += 1
                    continue
                
                limba = re.search('[a-zA-Z ()]*&', limbi[i_lb]).group()
                limba = limba[0 : len(limba) - 1]
                updated = re.search('updated/[0-9]+/[0-9]+/[0-9]+', limbi[i_lb])
                # 4. caut linkul
                link = None
                # download most updated
                if updated: 
                    link = updated.group()
                # download original
                else:
                    original = re.search('original/[0-9]+/[0-9]+', limbi[i_lb])
                    if original:
                        link = original.group()
                        
                if link != None:
                    versiune = re.search(' .+,', ver_split[i_ver - 1]).group()
                    versiune = versiune[0 : len(versiune) - 1]
                    self.__tabel_sub.append({'versiune': versiune,
                                             'limba': limba,
                                             'link': link})
											 
                i_lb += 1
            
            i_ver += 2
            
    def printSubtitrari(self):
        nr_subs_len = len(str(len(self.__tabel_sub)))
        max_ver_len = 0
        for sub in self.__tabel_sub:
            if len(sub['versiune']) > max_ver_len:
                max_ver_len = len(sub['versiune'])
				
        if max_ver_len < len('Verision'):
            max_ver_len = len('Verision')
			
        sub_str = ('# ' + ' ' * (nr_subs_len - 1) + ' |  ' + 'Version' + 
            ' ' * (max_ver_len - len(' Version')) + ' |  Language')
        sub_str_len = len(sub_str)
        sub_str += '\n' + '-' * sub_str_len
        i = 1
        for sub in self.__tabel_sub:
            i_str = str(i)
            sub_str += ('\n' + i_str + '.' + ' ' * (nr_subs_len - len(i_str)) + 
                ' | ' + sub['versiune'] + 
                ' ' * (max_ver_len - len(sub['versiune'])) + ' |  ' +
                sub['limba'])
            i += 1
			
        return sub_str
        
    def download(self, fis, url):
        sub = self.deschideURL(url)
        with open(fis, 'wb') as f:
            f.write(sub.read())
        
    def downloadSubtitrare(self, nr):
        fis = (self.__dl_dir + self.serial.nume + '_s' + self.serial.sezon +
               '_e' + self.serial.episod + '_' + 
               self.__tabel_sub[nr]['versiune'].replace(' ', '_') +
               '_' + self.__tabel_sub[nr]['limba'].replace(' ', '_') + '.srt')
        self.download(fis, 'http://www.addic7ed.com/' + 
                      self.__tabel_sub[nr]['link'])
        return fis
        
    def final(self):
        with open(self.__fis_cfg, 'w') as f:
            if len(self.__alias) > 0:
                f.write('[alias]\n')
                for k, v in self.__alias.iteritems():
                    f.write(k + '=' + v + '\n')
            if self.__dl_dir != self.defaultDir():
                f.write('[dl_dir]\n')
                f.write(self.__dl_dir)
            
    # creeaza numele serialului dintr-o lista
    def creeazaSerial(self, l):
        serial_str = ''
        for s in l:
            serial_str += s + ' '
        return serial_str.rstrip()
        
    def ajutor(self):
        print('''
addict.py -al alias serial     create an alias for a show(no spaces)
addict.py -rm alias            delete an alias
addict.py -dd [dir]            changes the download directory to dir(no spaces)
                                    if no dir parameter, it resets the 
                                    download directory
addict.py -pal [alias]         prints the alias, if no alias paramater, it
                                    prints all the aliases
addict.py -pdd                 prints current download directory
addict.py -h                   help
addict.py show/alias sez ep    searches subtitles for show, season, episode
            ''')
            
    def cliDownload(self, com):
        self.config()
        if com[0] == '-al':
            if len(com) < 3:
                print('unknown command')
                self.ajutor()
                exit(1)
            if com[1] in self.__alias:
                print('alias already exists')
                print(com[1] + ' = ' + self.__alias[com[1]])
                exit(1)
            else:
                self.__alias[com[1]] = self.creeazaSerial(com[2 : ])
        elif com[0] == '-rm':
            del self.__alias[com[1]]
        elif com[0] == '-dd':
            if len(com) == 1:
                self.__dl_dir = self.defaultDir()
            else:
                if not com[1].endswith(os.sep):
                    com[1] += os.sep
                self.__dl_dir = com[1]
        elif com[0] == '-pal':
            if len(com) == 2:
                if com[1] in self.__alias:
                    print(com[1] + ' = ' + self.__alias[com[1]])
                else:
                    print('no alias found')
            else:
                if len(self.__alias) > 0:
                    print('Aliases: ')
                    for k, v in self.__alias.iteritems():
                        print(k + ': ' + v)    
        elif com[0] == '-pdd':
            print('Downlaod dir: ' + self.__dl_dir)
        elif com[0] == '-h':
            self.ajutor()
        elif '-' in com[0]:
            print('unknown command')
            self.ajutor()
            exit(1)
        else:
            com_len = len(com)
            serial = self.creeazaSerial(com[0 : com_len - 2])
            if serial in self.__alias:
                self.serial.nume = self.__alias[serial]
            else:
                self.serial.nume = serial
                
            self.serial.sezon = com[com_len - 2]
            self.serial.episod = com[com_len - 1]
            self.cautaSubtitrari()
            if len(self.__tabel_sub) == 0:
                print('no subtitles found')
                exit(0)
            print(self.serial)
            print(self.printSubtitrari())
                
        self.final()
        
if __name__ == '__main__':
    a = Addict()
    if len(sys.argv) > 1:
        a.cliDownload(sys.argv[1 : ])
    else:
        a.cliDownload(['-pal'])
        a.cliDownload(raw_input('show, season, episode(separated by \',\'): ')
            .split(','))
    
    if (len(sys.argv) == 1) or (len(sys.argv) > 1 and '-' not in sys.argv[1]):
        try:
            print('\n0. Cancel\n')
            sub = raw_input('Subtitle: ')
            sub = int(sub)
            if sub == 0:
                exit(0)
            sub = a.downloadSubtitrare(sub - 1)
            print('Downloaded: ' + sub)
			
        except ValueError:
            print('bad input')
            exit(1)
        except EOFError:
            print('EOF')
            exit(1)
			